#include <iostream>
using namespace std;

class A{
public:
    void f(){
        cout << __PRETTY_FUNCTION__ << endl;
    }

    virtual void g(){
        cout << __PRETTY_FUNCTION__ << endl;
    }
};

class B : public A{
public:
    void f(){
        cout << __PRETTY_FUNCTION__ << endl;
    }

    virtual void g(){
        cout << __PRETTY_FUNCTION__ << endl;
    }

    virtual void h(){
        cout << __PRETTY_FUNCTION__ << endl;
    }
};

class C{
public:
    void f(){
        cout << __PRETTY_FUNCTION__ << endl;
    }

    void g(){
        cout << __PRETTY_FUNCTION__ << endl;
    }
};

typedef void(*func)(void);

int main(){
    A a;
    B b;
    C c;
    A& ar = b;

    // 静态绑定
    // f不是虚函数，因此在编译期间就通过静态类型确定了会调用哪个函数
    b.f();
    ar.f();

    // 动态绑定
    // g是虚函数，因此在运行期间通过查询对象的虚函数表确定调用哪个函数
    b.g();
    ar.g();

    // B类增添了一个在A类中不存在的虚函数h，这种情况下，是无法通过A类引用访问h的
    b.h();
    //ar.h();

    // 有虚函数的对象比没有虚函数的对象要大，因为它要额外存储一个指向虚函数表的指针
    cout << sizeof(a) << endl;
    cout << sizeof(b) << endl;
    cout << sizeof(c) << endl;

    return 0;
}
